﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.DependencyInjection;

namespace Fast.NormalizeActionResult
{
    /// <summary>
    /// RESTful 风格返回结果
    /// </summary>
    public class DefaultActionResultProvider : IActionResultProvider, ISingletonDependency
    {
        /// <summary>
        /// 获取异常结果
        /// </summary>
        /// <param name="context"></param>
        /// <param name="metadata"></param>
        /// <returns></returns>
        public virtual IActionResult GetExceptionResult(ExceptionContext context, ExceptionMetadata metadata)
            => new JsonResult(BuildRESTfulActionResult(metadata.Code, false, null, metadata.Message, metadata.ValidationErrors));

        /// <summary>
        /// 获取成功结果
        /// </summary>
        /// <param name="context"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public virtual IActionResult GetSucceededResult(ActionExecutedContext context, object data)
            => new JsonResult(BuildRESTfulActionResult($"{StatusCodes.Status200OK}", true, data));

        /// <summary>
        /// 获取验证失败结果
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public virtual IActionResult GetValidateFailedResult(ActionExecutingContext context, ValidationMetadata metadata)
            => new JsonResult(BuildRESTfulActionResult($"{StatusCodes.Status400BadRequest}", false, null, metadata.Message));

        /// <summary>
        /// 构造 <see cref="RESTfulActionResult{T}"/> 对象
        /// </summary>
        /// <param name="code"></param>
        /// <param name="hasSuccessful"></param>
        /// <param name="data"></param>
        /// <param name="message"></param>
        /// <param name="validationErrors"></param>
        /// <returns></returns>
        private RESTfulActionResult<object> BuildRESTfulActionResult(
            string code, bool hasSuccessful, object data = null,
            string message = null, ValidationErrorInfo[] validationErrors = null)
            => new RESTfulActionResult<object>
            {
                Code = code,
                HasSuccessful = hasSuccessful,
                Data = data,
                Message = message,
                ValidationErrors = validationErrors
            };
    }
}
